!< 1-D Burgers Equation solver
module datatype
    implicit none
    integer, parameter::pre = 8, n = 201 !< total cells = 200
    real, parameter::cfl = 0.5
    integer::i, j, iter = 0, if_cfl = 1
    integer::fileno = 1
    real(pre)::mul, t_end, dt, t, dx
    real(pre)::top = 1.0, low = -1.0
    real(pre)::max_u

    type var
        real(pre), pointer::u(:)
        real(pre), pointer::f(:) !< f = 0.5 * u**2
        real(pre), pointer::du(:)
        real(pre)::res, x
    end type var
    type(var), pointer:: cell(:)

end module

subroutine solver
    use datatype
    implicit none

    call bc_init
    call cfd_procs
    call tec_out

    return
end subroutine

subroutine bc_init
    use datatype
    implicit none
    allocate (cell(1:n))
    write (*, '(A10)', advance='no') 'Input mul:'
    read (*, *) mul
    write (*, '(A12)', advance='no') 'Input t_end:'
    read (*, *) t_end

    t = 0.0
    !mul = 0.01
    !t_end = 4.0
    dt = 0.0001
    dx = 2.0/(n - 1)

    do i = 1, n
        allocate (cell(i)%du(1:5), cell(i)%u(1:2), cell(i)%f(1:2)) !< 1 ~ du/dt; 2~du/dx; 3~d2u/dtdx;
    end do                                                                                                   !< 4~d3u/dtd2x; 5~d2u/dt2

    !< init & boundary
    cell(1)%x = -1.0; cell(1)%u = 0.5
    cell(n)%x = 1.0; cell(n)%u = -0.5
    cell(1)%f = cell(1)%u**2
    cell(n)%f = cell(n)%u**2
    do i = 2, n - 1
        cell(i)%x = cell(1)%x + (cell(n)%x - cell(1)%x)/n*i
        cell(i)%u = (-0.5)*cell(i)%x
        cell(i)%f = cell(i)%u**2
    end do

    return
end subroutine

subroutine cfd_procs
    use datatype
    implicit none

    do while (t <= t_end)
        do i = 2, n - 1
            cell(i)%du(1) = mul*(cell(i + 1)%u(1) - 2*cell(i)%u(1) + cell(i - 1)%u(1))/(dx**2) &
                            - cell(i)%u(1)*(cell(i + 1)%u(1) - cell(i - 1)%u(1))/(2*dx) 

            cell(i)%du(2) = (cell(i + 1)%u(1) - cell(i - 1)%u(1))/(2*dx) !< du/dx

            cell(i)%du(3) = (cell(i + 1)%du(1) - cell(i - 1)%du(1))/(2*dx) !< d2u/dtdx

            cell(i)%du(4) = (cell(i + 1)%du(1) - 2*cell(i)%du(1) + cell(i - 1)%du(1))/(2*dx) !< d3u/dtd2x

            cell(i)%du(5) = mul*cell(i)%du(4) - cell(i)%du(1)*cell(i)%du(2) - cell(i)%u(1)*cell(i)%du(3) !< d2u/dt2

            cell(i)%u(2) = cell(i)%u(1) + cell(i)%du(1)*dt + cell(i)%du(5)*(dt**2)/2

            cell(i)%u(1) = cell(i)%u(2)
        end do
        t = t + dt
        iter = iter + 1
    end do

    return
end subroutine

subroutine tec_out
    use datatype
    implicit none

    open (unit=fileno, file='Lax-Wendroff.plt', form='formatted')
    write (fileno, *) 'variables = "x", "u"'
    do i = 1, n
        write (fileno, *) cell(i)%x, cell(i)%u(2)
    end do
    close (fileno)
    write (*, '(A5, I7)') 'Iter:', iter

    return
end subroutine

program Lax_Wendroff
    use datatype
    implicit none

    call solver

    stop
end program 
